﻿using System.ServiceProcess;
using System;
using System.Collections;

namespace NetfractionHub
{
	static class Program
	{
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		static int Main(string[] args)
		{
			bool install = false, uninstall = false, console = true, service = false, rethrow = false;
			try
			{
				foreach (string arg in args)
				{
					switch (arg)
					{
						case "-i":
						case "-install":
							install = true;
							break;
						case "-u":
						case "-uninstall":
							uninstall = true;
							break;
						case "-c":
						case "-console":
							console = true;
							break;
						case "-s":
						case "-service":
							console = false;
							service = true;
							break;
						default:
							Console.Error.WriteLine("Argument not expected: " + arg);
							break;
					}
				}

				// Act on the conditions
				if (uninstall)
					Install(true, args); 
				else if (install) 
					Install(false, args); 
 
				if (console) 
				{
					Console.WriteLine("Starting NetfractionHub {0}...", System.Reflection.Assembly.GetEntryAssembly().GetName().Version);
					NetfractionHubService nhs = new NetfractionHubService();
					nhs.StartApplication();
					Console.WriteLine("System running; press any key to stop"); 
					Console.ReadKey(true);

					nhs.StoppingApplication();
					Console.WriteLine("System stopped");
				}
				else if (service) 
				{ 
					rethrow = true; // so that Windows sees error... 
					ServiceBase[] services = { new NetfractionHubService() }; 
					ServiceBase.Run(services); 
					rethrow = false; 
				}
				return 0; 
			} 
			catch (Exception ex) 
			{ 
				if (rethrow) throw; 
				Console.Error.WriteLine(ex.Message); 
				return -1; 
			} 
		}

		static void Install(bool undo, string[] args)
		{
			try
			{
				Console.WriteLine(undo ? "uninstalling" : "installing");

				// Probably want to call an external app to do the actual service install since this requires an elevation of privilege
				/*using (AssemblyInstaller inst = new AssemblyInstaller(typeof(Program).Assembly, args))
				{
					IDictionary state = new Hashtable();
					inst.UseNewContext = true;
					try
					{
						if (undo)
							inst.Uninstall(state);
						else
							inst.Install(state);
							inst.Commit(state);
					}
					catch
					{
						try
						{
							inst.Rollback(state);
						}
						catch { }
						throw;
					}
				}*/
			}
			catch (Exception ex)
			{
				Console.Error.WriteLine(ex.Message);
			} 
		}
	}
}
